package com.base.component.app.pay.weixin;

import java.nio.charset.StandardCharsets;
import java.security.Signature;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import com.base.component.app.pay.bo.PayWxJsapiBO;
import com.base.component.app.pay.bo.PayWxJsapiVO;
import com.gitee.magic.core.exception.ApplicationException;
import com.gitee.magic.core.utils.StringUtils;
import com.gitee.magic.core.utils.codec.Base64;
import com.gitee.magic.framework.base.utils.IpUtils;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.util.PemUtil;
import com.wechat.pay.java.service.payments.jsapi.JsapiService;
import com.wechat.pay.java.service.payments.jsapi.model.Amount;
import com.wechat.pay.java.service.payments.jsapi.model.Payer;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayRequest;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayResponse;
import com.wechat.pay.java.service.payments.jsapi.model.SceneInfo;

/**
 * 微信jspi支付
 * 
 * @author mac
 *
 */
public class WeixinJspiPayHandler extends WeixinBasePayHandler<PayWxJsapiVO,PayWxJsapiBO> {

	@Override
	public boolean support(String name, Class<?> prototype) {
		return true;
	}
	
	@Override
	public PayWxJsapiVO prepay(PayWxJsapiBO bo) {
		Config config =getConfig();
		JsapiService service=new JsapiService.Builder().config(config).build();
		PrepayRequest prepayRequest = new PrepayRequest();
		prepayRequest.setAppid(appId);
		prepayRequest.setMchid(merchantId);
		prepayRequest.setDescription(bo.getDescription());
		prepayRequest.setNotifyUrl(weixinPayDomain+ "/v1/pay/notify/"+bo.getOrderId());
		prepayRequest.setOutTradeNo(String.valueOf(bo.getOrderId()));
		Amount amount = new Amount();
		amount.setTotal(bo.getPrice());
		prepayRequest.setAmount(amount);
		Payer p=new Payer();
		p.setOpenid(bo.getOpenId());
		prepayRequest.setPayer(p);
		SceneInfo sceneInfo = new SceneInfo();
		sceneInfo.setPayerClientIp(IpUtils.getRequestIp(request));
		prepayRequest.setSceneInfo(sceneInfo);
		PrepayResponse response = service.prepay(prepayRequest);
		
		PayWxJsapiVO vo = new PayWxJsapiVO();
		vo.setPrepayId("prepay_id=" + response.getPrepayId());
        Long timeStamp = System.currentTimeMillis() / 1000;
        vo.setTimeStamp(timeStamp);
        String nonceStr = StringUtils.random();
        vo.setNonceStr(nonceStr);
        String signatureStr = Stream.of(
        		appId, 
        		String.valueOf(timeStamp), 
        		nonceStr, 
        		vo.getPrepayId()).collect(Collectors.joining("\n", "", "\n"));
        try {
			Signature sign = Signature.getInstance("SHA256withRSA");
	        sign.initSign(PemUtil.loadPrivateKeyFromString(privateKey));
	        sign.update(signatureStr.getBytes(StandardCharsets.UTF_8));
	        vo.setPaySign(Base64.encode(sign.sign()));
		} catch (Exception e) {
			throw new ApplicationException(e);
		}
		return vo; 
	}

}
